package prv.pursuivant.render.html;

import static org.junit.Assert.assertEquals;

import java.io.StringWriter;
import java.util.Date;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.junit.Before;
import org.junit.Test;

import prv.pursuivant.core.AchievType;
import prv.pursuivant.core.AchievTypesTree;
import prv.pursuivant.core.AchievTypesTreeImpl;
import prv.pursuivant.core.Achievement;
import prv.pursuivant.core.AchievementCalculator;
import prv.pursuivant.core.AllAchievements;
import prv.pursuivant.core.Toon;
import prv.pursuivant.core.impl.AchievementCalculatorImpl;
import prv.pursuivant.core.impl.AchievementImpl;
import prv.pursuivant.core.impl.AllAchievementsImpl;
import prv.pursuivant.core.impl.CategoryAchievType;
import prv.pursuivant.core.impl.NormalAchievType;
import prv.pursuivant.core.impl.NpcAchievType;
import prv.pursuivant.core.impl.ToonImpl;
import prv.pursuivant.render.OutputGenerator;
import prv.pursuivant.util.DateUtil;

import com.google.inject.internal.Lists;

public class HtmlDataRendererTest {

	private Toon kwinto;
	private HtmlDataRenderer renderer;
	private AchievementCalculator calculator;
	private AchievType naxx;
	private AchievTypesTree tree;
	private AllAchievements achievements;
	private AchievType q1anub;
	private AchievType q1;
	private DateUtil dateUtil;
	private Date testWhen;
	private StringWriter writer;
	private OutputGenerator generator;

	@Before
	public void setUp() throws XMLStreamException {
		kwinto = new ToonImpl("Kwinto", 3);
		q1anub = new NpcAchievType("Anub'Rekhan", "562");
		AchievType q1b = new NpcAchievType("Maexxna", "562");
		AchievType q1c = new NpcAchievType("Grand Widow Faerlina", "562");
		q1 = new NormalAchievType("The Arachnid Quarter", "562", Lists
				.newArrayList(q1anub.getId(), q1b.getId(), q1c.getId()));
		naxx = new NormalAchievType("The Fall of Naxxramas", "576", Lists
				.newArrayList(q1.getId()));
		tree = new AchievTypesTreeImpl(Lists.newArrayList(naxx, q1, q1anub,
				q1b, q1c), new CategoryAchievType("Dungeons & Raids", "168",
				Lists.newArrayList("576")));
		dateUtil = new DateUtil();
		testWhen = dateUtil.createDate(2008, 12, 13);

		Achievement anub = new AchievementImpl(kwinto, dateUtil.createDate(
				2008, 12, 13), q1anub.getId());
		Achievement maexxna = new AchievementImpl(kwinto, dateUtil.createDate(
				2008, 12, 14), q1b.getId());
		achievements = AllAchievementsImpl.fromCollection(Lists.newArrayList(
				anub, maexxna));

		calculator = new AchievementCalculatorImpl(tree, achievements);
		renderer = new HtmlDataRenderer(calculator, dateUtil);
		writer = new StringWriter();
		XMLStreamWriter xmlWriter = XMLOutputFactory.newInstance()
				.createXMLStreamWriter(writer);
		generator = new XHtmlGenerator(xmlWriter);

	}

	@Test
	public void shouldRenderToonText() throws XMLStreamException {
		renderer.renderToonText(generator, kwinto);
		String actual = writer.toString();
		assertEquals("Kwinto", actual);
	}

	@Test
	public void shouldFormatCriteriaName() {
		String actual = renderer.formatCriteriaName(naxx.getName());
		String expected = "The Fall of Naxx ramas";
		assertEquals(expected, actual);
	}

	@Test
	public void shouldRenderNormalCriteriaText() {
		renderer.renderCriteriaText(generator, naxx);
		String actual = writer.toString();
		String expected = "<a href=\"http://www.wowhead.com/?achievement=576\">"
				+ renderer.formatCriteriaName(naxx.getName()) + "</a>";
		assertEquals(expected, actual);
	}

	@Test
	public void shouldRenderAchievNotDoneText() {
		renderer.renderAchievText(generator, kwinto, naxx, testWhen);
		String actual = writer.toString();
		String expected = "&nbsp;";
		assertEquals(expected, actual);
	}

	@Test
	public void shouldRenderAchievCompletelyDoneText() {
		renderer.renderAchievText(generator, kwinto, q1anub, testWhen);
		String actual = writer.toString();
		String expected = dateUtil.format(testWhen);
		assertEquals(expected, actual);
	}

	@Test
	public void shouldRenderAchievPartlyDoneText() {
		renderer.renderAchievText(generator, kwinto, q1, testWhen);
		String actual = writer.toString();
		String expected = "1/3";
		assertEquals(expected, actual);
	}

}
